package com.t114514.demo.controller;

import com.t114514.demo.pojo.Result;
import com.t114514.demo.pojo.Student;
import com.t114514.demo.pojo.Teacher;
import com.t114514.demo.pojo.User;
import com.t114514.demo.service.StudentService;
import com.t114514.demo.service.TeacherService;
import com.t114514.demo.service.UserService;
import com.t114514.demo.utils.JwtUtil;
import com.t114514.demo.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import org.apache.ibatis.jdbc.Null;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import org.mindrot.jbcrypt.BCrypt;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/registerTeacher")
    public Result registerTeacher(@Pattern(regexp = "^\\S{6,20}$") String teacherAccount, @Pattern(regexp = "^\\S{5,16}$") String password, @Pattern(regexp = "^\\S{2,10}$") String teacherName) {
        //
        Teacher t = teacherService.findTeacher(teacherAccount);
        String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        if (t == null) {
            teacherService.addTeacher(teacherAccount, hashedPassword,teacherName);
            return Result.success();
        }
        else{
            return Result.error("用户已存在");

        }
    }

    @PostMapping("/registerStudent")
    public Result register(@Pattern(regexp = "^\\S{6,20}$") String studentAccount, @Pattern(regexp = "^\\S{5,16}$") String password, @Pattern(regexp = "^\\S{2,10}$") String studentName) {
        //
        Student s = studentService.findStudent(studentAccount);
        String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        if (s == null) {
            studentService.addStudent(studentAccount, hashedPassword,studentName);
            return Result.success();
        }
        else{
            return Result.error("用户已存在");

        }
    }
    @PostMapping("/registerUser")
    public Result registerUser(@Pattern(regexp = "^\\S{6,20}$") String userAccount, @Pattern(regexp = "^\\S{5,16}$") String password) {
        User loginUser = userService.findUser(userAccount);
        if (loginUser == null) {
            String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
            userService.addUser(userAccount, hashedPassword);
            return Result.success();
        }
        else{
            return Result.error("用户已存在");

        }

    }

    @PostMapping("/loginTeacher")
    public Result<String> loginTeacher(@Pattern(regexp = "^\\S{6,20}$") String teacherAccount, @Pattern(regexp = "^\\S{5,16}$") String password) {

        Teacher loginTeacher = teacherService.findTeacher(teacherAccount);

        if (loginTeacher == null) {
            return Result.error("用户不存在");
        }

        if (BCrypt.checkpw(password, loginTeacher.getTeacherPassword())) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("UserType", 2);
            claims.put("Account",teacherAccount);
//            claims.put("usertype",loginUser.getUsertype());
            String token = JwtUtil.genToken(claims);
            ValueOperations<String, String> operations=stringRedisTemplate.opsForValue();
            operations.set(token,token,24, TimeUnit.HOURS);
            return Result.success(token);
        }

        return Result.error("密码错误");

    }

    @PostMapping("/loginStudent")
    public Result<String> loginStudent(@Pattern(regexp = "^\\S{6,20}$") String studentAccount, @Pattern(regexp = "^\\S{5,16}$") String password) {

        Student loginStudent = studentService.findStudent(studentAccount);

        if (loginStudent == null) {
            return Result.error("用户不存在");
        }

        if (BCrypt.checkpw(password, loginStudent.getStudentPassword())) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("UserType", 1);
            claims.put("Account",studentAccount);
//            claims.put("usertype",loginUser.getUsertype());
            String token = JwtUtil.genToken(claims);
            ValueOperations<String, String> operations=stringRedisTemplate.opsForValue();
            operations.set(token,token,24, TimeUnit.HOURS);
            return Result.success(token);
        }

        return Result.error("密码错误");

    }

    @PostMapping("/loginUser")
    public Result<String> loginUser(@Pattern(regexp = "^\\S{6,20}$") String userAccount, @Pattern(regexp = "^\\S{5,16}$") String password) {
        User loginUser = userService.findUser(userAccount);
        if (loginUser == null) {
            return Result.error("用户不存在");
        }
        if (BCrypt.checkpw(password, loginUser.getPassword())) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("UserType", 3);
            claims.put("Account",userAccount);
//            claims.put("usertype",loginUser.getUsertype());
            String token = JwtUtil.genToken(claims);
            ValueOperations<String, String> operations=stringRedisTemplate.opsForValue();
            operations.set(token,token,24, TimeUnit.HOURS);
            return Result.success(token);
        }

        return Result.error("密码错误");

    }


    @GetMapping("/studentInfo")
    public Result<Student> studentInfo() {
        Map<String,Object> map= ThreadLocalUtil.get();
        String studentAccount=(String) map.get("Account");
        Student student = studentService.findStudent(studentAccount);
        if (student == null) {
            return Result.error("用户不存在");
        }
        return Result.success(student);
    }

    @GetMapping("/teacherInfo")
    public Result<Teacher> teacherInfo() {
        Map<String,Object> map= ThreadLocalUtil.get();
        String teacherAccount=(String) map.get("Account");
        Teacher teacher = teacherService.findTeacher(teacherAccount);
        if (teacher == null) {
            return Result.error("用户不存在");
        }
        return Result.success(teacher);
    }

    @PutMapping("/updateStudent")
    public Result update(@RequestBody Student student) {
        System.out.print(student.getStudentAccount());
        Student updateStudent=studentService.findStudent(student.getStudentAccount());
        System.out.print(updateStudent);
        if (updateStudent==null)
            return Result.error("用户不存在");
        if (BCrypt.checkpw(student.getStudentPassword(), updateStudent.getStudentPassword()))
            return Result.error("密码不能与上次一致");
        if(student.getStudentName()!=null)
            updateStudent.setStudentName(student.getStudentName());
//        if (student.getStudentAvatar()!=null)
//            updateStudent.setStudentAvatar(student.getStudentAvatar());
        if (student.getStudentPassword()!=null)
            updateStudent.setStudentPassword(BCrypt.hashpw(student.getStudentPassword(), BCrypt.gensalt()));
        studentService.modifyStudent(updateStudent);
        return Result.success();
    }

    @PutMapping("/updateTeacher")
    public Result update(@RequestBody Teacher teacher) {
        Teacher updateTeacher=teacherService.findTeacher(teacher.getTeacherAccount());
        if (updateTeacher==null)
            return Result.error("用户不存在");
        if (BCrypt.checkpw(teacher.getTeacherPassword(), updateTeacher.getTeacherPassword()))
            return Result.error("密码不能与上次一致");
//        if(teacher.getTeacherName()!=null)
//            updateTeacher.setTeacherName(teacher.getTeacherName());
        if (teacher.getTeacherPassword()!=null)
            updateTeacher.setTeacherPassword(BCrypt.hashpw(teacher.getTeacherPassword(), BCrypt.gensalt()));
        teacherService.modifyTeacher(updateTeacher);
        return Result.success();
    }

    @GetMapping("/getUserType")
    public Result<Integer> getUserType() {
        Map<String,Object> map= ThreadLocalUtil.get();
        int UserType=(int) map.get("UserType");
        return Result.success(UserType);
    }

}
